home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / bcfamily / source / datetime.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-12  |  2.5 KB  |  90 lines

  1. //
  2. //      *******************************************************************
  3. //        JdeBP C++ Library Routines          General Public Licence v1.00
  4. //            Copyright (c) 1991,1992     Jonathan de Boyne Pollard
  5. //      *******************************************************************
  6. //
  7. // Part of FamAPI.LIB
  8. //
  9.  
  10. #include "famapi.h"
  11. #include "dosdos.h"
  12.  
  13. #define ISLEAP(yr)    ( ((yr)%4==0) && ( ((yr)%100!=0) || ((yr)%400==0) ) )
  14.  
  15. //
  16. //    Return the day of the week for a given year/month/day
  17. //
  18. static USHORT pascal
  19. DosGetWeekDay ( unsigned int year,
  20.                 unsigned char mon,
  21.                 unsigned char mday,
  22.                 unsigned char far *PtrWeekDay )
  23. {
  24.     static const unsigned char month[] = { 1,4,4, 0,2,5, 0,3,6, 1,4,6 };
  25.  
  26. #define wday    (*PtrWeekDay)
  27.  
  28.     // This algorithm from Martin Gardner's column in Scientific American
  29.     //
  30.     // This algorithm relies on the fact that Jan 01 1900 was a Sunday
  31.     // (Day 1) and counts onward from there.  It uses a fast tabular method
  32.     // for the months and bit shifting for the years.  To avoid doing
  33.     // division until the last possible moment, we do not work modulo 7.
  34.     // Since the largest accumulated value (Dec 31 2099) is only 321, which
  35.     // is well within INT_MAX, we need not worry about integer overflow.
  36.  
  37.     wday = 0;
  38.     while (year > 100) {
  39.         if ((year / 100) % 4 != 0)
  40.             wday -= 2;        // Centuries beginning with leap years lose only
  41.         else                // one weekday over the whole century.  Those not
  42.             wday -= 1;        // so beginning lose two.
  43.         year -= 100;
  44.     }
  45.     wday += year + (year >> 2) + month[mon-1] + mday;
  46.     if (ISLEAP(year) && mon < 2) wday--;
  47.  
  48.     // Sneaky trick to avoid division.  In any base n, the remainder when
  49.     // a number M is divided by (n-1) is equal to the sum of the digits of
  50.     // M (base n) modulo (n-1).
  51.  
  52.     while (wday > 7)
  53.         wday = (wday & 7) + ((wday & ~7) >> 3);
  54.  
  55.     // Standard C library dictates Sunday = 0 whereas this algorithm says
  56.     // Sunday = 1
  57.     --wday ;
  58.  
  59. #undef wday
  60.  
  61.     return 0 ;
  62. }
  63.  
  64. //
  65. //    Retrive current date and time
  66. //
  67. USHORT _APICALL
  68. DosGetDateTime ( DOSDATETIME far *PtrDateTime )
  69. {
  70.     PtrDateTime->timezone = 0 ;        // Assume GMT
  71.  
  72.     _AH = 0x2a ;
  73.     Dos3Call() ;
  74.     PtrDateTime->year = _CX ;
  75.     PtrDateTime->month = _DH ;
  76.     PtrDateTime->day = _DL ;
  77.  
  78.     _AH = 0x2c ;
  79.     Dos3Call() ;
  80.     PtrDateTime->hours = _CH ;
  81.     PtrDateTime->minutes = _CL ;
  82.     PtrDateTime->seconds = _DH ;
  83.     PtrDateTime->hundredths = _DL ;
  84.  
  85.     return DosGetWeekDay ( PtrDateTime->year - 1900,
  86.                            PtrDateTime->month,
  87.                            PtrDateTime->day,
  88.                           &PtrDateTime->weekday ) ;
  89. }
  90.